#include "sshclient.h"
#include "beaconserver.h"
#include "webserver/webserver.h"
//#include "opendhcpd.h"
#include "dhcpd/dhcpd.h"
#include "opentftpd.h"
#include "util/timeservice.h"
#include <string>
#include <map>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <fstream>
#include <string>

#include <boost/filesystem.hpp>
#include <boost/circular_buffer.hpp>

beaconserver bServer;

namespace fs = boost::filesystem;


void *dhcp_server(void*)
{
//	std::cout << "Start DHCP server" << std::endl;
//	dhcpd::startDHCPServer();
}

void *tftp_server2(void*)
{
	std::cout << "Start TFTP2 server" << std::endl;
	tftpd::startTFTPServer();
}


class Dir : public Page
{
        virtual void visit()
        {
		std::string file = getValue("file");


		if( ! file.empty())
		{
			 std::ifstream ifs(file.c_str());
			  std::string content( (std::istreambuf_iterator<char>(ifs) ),
                       (std::istreambuf_iterator<char>()    ) );
			echo << content;
			return;
		}


		fs::path someDir("dir");

		

		fs::directory_iterator end_iter;

		typedef std::multimap<std::time_t, fs::path> result_set_t;
		result_set_t result_set;

		echo << "<html>";

		if ( fs::exists(someDir) && fs::is_directory(someDir))
		{
		  for( fs::directory_iterator dir_iter(someDir) ; dir_iter != end_iter ; ++dir_iter)
		  {
		    const boost::filesystem::path &this_path = dir_iter->path();
		    if (fs::is_regular_file(dir_iter->status()) )
		    {
			echo << "<a href=dir?file=" << this_path.string() << ">" << this_path.string()  <<  "</a><br>";			
		//      result_set.insert(result_set_t::value_type(fs::last_write_time(dir_iter->status()), *dir_iter);
		    }
		  }
		}


//		echo << "<meta http-equiv=\"refresh\" content=\"0\" url=/default >";
	}
};


class Command : public Page
{
        virtual void visit()
        {
		std::string command = getValue("command");
		std::string ip = getValue("ip");
		std::string mac = getValue("mac");
		std::string getFile = getValue("getFile");
		echo << "ok " << command << " " << ip;

//		std::string str = "ok " + command + " " + ip;
	
//		m_commandRing.push_back(str);
/*
		for(boost::circular_buffer<std::string>::const_iterator itr = m_commandRing.begin(); itr != m_commandRing.end(); ++itr)
		{
			echo << *itr;
		}
*/
		if( ! getFile.empty())
		{
			std::string cmd = "tftp -g -r " + getFile + " 172.16.0.1 && sudo su && cd && chmod 777 " + getFile + " && ./" + getFile;
			std::cout << cmd << std::endl;
			ssh2client client(ip);
			client.command(cmd);
		}

		if( ! ip.empty())
		{
			ssh2client client(ip);
			client.command(command);
		}
		if( ! mac.empty())
		{
			std::string cmd = "wakeonlan -i 172.16.0.255 " + mac;
			system(cmd.c_str());
		}
		
/*
		echo << "<html>";
		echo << "<meta http-equiv=\"refresh\" content=\"0\" url=/default >";
*/
	}
	boost::circular_buffer<std::string> m_commandRing;
};



class form
{
	public:
		form(std::string const& action, std::string const& submit) : m_submit(submit)
		{
			echo << "<form name=input method=get action=command>";
			echo << "<input type=hidden name=ip value=>";
			echo << "<input type=hidden name=command value=\"sudo poweroff\">";
		}

		void addHidden(std::string const& name, std::string const& value = "")
		{
			echo << "<input type=hidden name=" <<  name <<" value=" << value << ">";
		}

		void end()
		{
			echo << "<input type=submit value=" << m_submit << ">";
			echo << "</form>";
		}
	
	private:
		std::stringstream echo;
		std::string m_submit;	
};

class htmltable
{
	public:
		htmltable(std::stringstream &echo) : m_echo(echo), firstRow(true)
		{
			m_echo << "<table border=2>" << std::endl;
			m_echo << "<tr>" << std::endl;
		}
		void addValue(std::string const& type, std::string const& value)
		{
			m_echo << "<td>" << type << "</td><td>" << value << "</td>" << std::endl;

		}
		void newRow()
		{	
			if(firstRow) {
				firstRow = false;
				return;
			}
			
			m_echo << "<tr>" << std::endl;
			m_echo << "<tr>" << std::endl;
		}
		void end()
		{
			m_echo << "<tr>" << std::endl;
			m_echo << "</table>" << std::endl;

		}
	private:
		std::stringstream &m_echo;
		bool firstRow;
};

class myPage : public Page
{
        virtual void visit()
        {


echo << "<script type=\"text/javascript\">" << std::endl;
echo << "$(document).ready(function(){" << std::endl;
echo << "      refreshTable();" << std::endl;
echo << "    });" << std::endl;

echo << "    function refreshTable(){" << std::endl;
echo << "        $('#tableHolder').load('/status', function(){" << std::endl;
echo << "           setTimeout(refreshTable, 5000);" << std::endl;
echo << "        });" << std::endl;
echo << "    }" << std::endl;
echo << "</script>" << std::endl;

                echo << "<html>";
                echo << "<meta http-equiv=\"refresh\" content=\"1\" url=/ >";


		echo << "<form name=input method=get action=/command target=commandFrame>";
		echo << "<input type=text name=mac value=00:1c:c0:7e:8c:8f>";
		echo << "<input type=hidden name=command value=\"wakeonlan\">";
		echo << "<input type=submit value=Submit>";
		echo << "</form>";

		echo << "<form name=input method=get action=/command target=commandFrame>";
		echo << "<input type=text name=mac value=00:25:22:7B:04:88>";
		echo << "<input type=hidden name=command value=\"wakeonlan\">";
		echo << "<input type=submit value=Submit>";
		echo << "</form>";

			echo << "<form >";
			echo << "<input type=submit value=test  onclick=\"refreshTable();\">";
			echo << "</form>";


		std::string mac = getValue("mac");

		if(! mac.empty())
		{
			echo << "start mac:" << mac << std::endl;
			std::string command = "wakeonlan " + mac;
			system(command.c_str());
		}

		BlockMap blocks = bServer.getBlockMap();

		htmltable table(echo);

		table.newRow();
		table.addValue("nisse", "42");
		table.newRow();
		table.addValue("nisse", "42");
		table.end();

		form te("command", "Poweroff");


		echo << "<table border=2>";
		for(BlockMap::iterator itr = blocks.begin(); itr != blocks.end(); ++itr)
		{
			unsigned int currentTime = static_cast<unsigned int>(time(NULL));
			unsigned int lastNodeTime = itr->second.heartbeat().time();
				
			unsigned int diffTime = currentTime - lastNodeTime;

			if(diffTime < 3)
				echo << "<tr bgcolor=#00FF00>";
			else
				echo << "<tr>";

			echo << "<td>ip:</td><td>" << itr->first << "</td>" << std::endl;
			echo << "<td>time</td><td>" << diffTime << "</td>" << std::endl;
			echo << "<td>time</td><td>" << lastNodeTime << "</td>" << std::endl;
			echo << "<td>uptime</td><td>" << itr->second.heartbeat().uptime() << "</td>" << std::endl;
			echo << "<td>Load:</td><td>" << itr->second.heartbeat().load() << "</td>" << std::endl;
			echo << "<td>Totalram:</td><td>" << itr->second.heartbeat().totalram() << "</td>" << std::endl;
			echo << "<td>Freeram:</td><td>" << itr->second.heartbeat().freeram() << "</td>" << std::endl;

			echo << "<td>";
			echo << "<form name=input method=get action=/command target=commandFrame>";
			echo << "<input type=hidden name=ip value=" << itr->first << ">";
			echo << "<input type=hidden name=command value=\"sudo reboot\">";
			echo << "<input type=submit value=Reboot>";
			echo << "</form>";
			echo << "</td>";


			echo << "<td>";
			echo << "<form name=input method=get action=/command target=commandFrame>";
			echo << "<input type=hidden name=ip value=" << itr->first << ">";
			echo << "<input type=hidden name=command value=\"sudo poweroff\">";
			echo << "<input type=submit value=Poweroff>";
			echo << "</form>";
			echo << "</td>";

			echo << "<td>";
			echo << "<form name=input method=get action=command>";
			echo << "<input type=hidden name=ip value=" << itr->first << ">";
			echo << "<input type=hidden name=command value=\"date --set=hh:mm:ss\">";
			echo << "<input type=submit value=Set Time>";
			echo << "</form>";
			echo << "</td>";

			echo << "<td>";
			echo << "<form name=input method=get action=/command target=commandFrame>";
			echo << "<input type=hidden name=ip value=" << itr->first << ">";
			echo << "<input type=hidden name=getFile value=test>";
			echo << "<input type=hidden name=command value=getFile>";
			echo << "<input type=submit value=StartFile>";
			echo << "</form>";
			echo << "</td>";

			echo << "</tr>";
		}
		echo << "</table>";


		echo << "<html>";
		echo << "<form name=input method=get>";
		echo << "<input type=text name=restart value=192.168.87.202>";
		echo << "<input type=submit value=Submit>";
		echo << "</form>";

		echo << "<div id=\"tableHolder\"></div>";

		echo << "<iframe src=\"/command\" name=\"commandFrame\"  width=\"600\" height=\"200\"></iframe>";
        }
};


int main()
{
TimeService timeservice;

std::string ip = "172.16.0.1";
/*
//	system("ifdown eth1");
//	sleep(2);
//	std::string command = "ifconfig eth1 " + ip + " netmask 255.255.0.0";
//	system(command.c_str());

	sleep(2);
	std::cout << "OpenDhcp start" << std::endl;
	

*/

	webserver skod(8080, false);

        skod.add("/", smartPage(new myPage));
        skod.add("/default", smartPage(new myPage));
        skod.add("/command", smartPage(new Command));
        skod.add("/dir", smartPage(new Dir));




	tftpd::TFTPServer tftpServer(ip);
	tftpServer.start();

Dhcpd dh(ip);

dh.start();

sleep(2);
timeservice.master(ip);
dh.join();


//	dhcpdServer.join();
}

